package gapidt.plugin;

import gapidt.analysis.detectors.InappropriateOrLackingCommentsDetector;
import gapidt.analysis.detectors.UndercoverFaultInformationDetector;
import gapidt.analysis.detectors.WhateverTypesDetector;
import gapidt.common.Locale;
import gapidt.common.StringUtils;
import gapidt.nlp.SemanticAnalyzer;
import gapidt.nlp.SemanticParser;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
 * The activator class controls the plug-in life cycle
 */
public class GapidtActivator extends AbstractUIPlugin {
	
	static Logger logger = Logger.getLogger(GapidtActivator.class);
	
	public static final String PLUGIN_ID = "gapidt";
	private static GapidtActivator plugin;	// The shared instance
	
	//Preferences identifiers	
	public static final String MIN_SIMILARITY_DEGREE_PREFERENCE = "min_similarity_degree";
	public static final String WHATEVER_TYPES_PREFERENCE = "whatever_types";
	public static final String UNDERCOVER_FAULT_NAMES_PREFERENCE = "undercover_fault_names";
	public static final String AMBIGUOUS_NAMES_PREFERENCE = "ambiguous_names";
	
	public GapidtActivator(){ }

	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		
		//Configures the Log4J from the file log4j.properties
		PropertyConfigurator.configure(getFilePath("/log4j.properties"));
		
		//Inicializar localizacion
		Locale.setLanguage((String) getDefault().getBundle().getHeaders().get("Bundle-Language"));
		
		//Sets the System properties from the file system.properties
		Properties p = new Properties(System.getProperties());
	    
		try {
			p.load(new FileInputStream(getFilePath("/system.properties")));
		    
		    //Corrects the relative paths
			if(p.getProperty("wordnet.database.dir") != null)
				p.setProperty("wordnet.database.dir", getFilePath(p.getProperty("wordnet.database.dir")));
			
			if(p.getProperty("gapidt.nlp.parserFile") != null)
				p.setProperty("gapidt.nlp.parserFile", getFilePath(p.getProperty("gapidt.nlp.parserFile")));
			
		    System.setProperties(p);
		    
		} catch (Exception e) {
			logger.error(e);
		}
		
		Integer storedMinSimilarityDegree = getPreferenceStore().getInt(MIN_SIMILARITY_DEGREE_PREFERENCE);
		if(storedMinSimilarityDegree != null)
			InappropriateOrLackingCommentsDetector.setMinSimilarityDegree(storedMinSimilarityDegree);
		
		String storedWhateverTypes = getPreferenceStore().getString(WHATEVER_TYPES_PREFERENCE);
		if(storedWhateverTypes != null)
			WhateverTypesDetector.setWhateverTypes(StringUtils.splitAndTrim(storedWhateverTypes));
		
		String storedUndercoverFaultNames = getPreferenceStore().getString(UNDERCOVER_FAULT_NAMES_PREFERENCE);
		if(storedUndercoverFaultNames != null)
			UndercoverFaultInformationDetector.setUndercoverFaultNames(StringUtils.splitAndTrim(storedUndercoverFaultNames));
		
		String storedAmbiguousWords = getPreferenceStore().getString(AMBIGUOUS_NAMES_PREFERENCE);
		if(storedAmbiguousWords != null)
			SemanticAnalyzer.setAmbiguousNames(StringUtils.splitAndTrim(storedAmbiguousWords));
		
		//Inicializar lexparser
		SemanticParser.init();
	}
	
	public static String getFilePath(String relativePath){
		Path path = new Path(relativePath);
		URL url = FileLocator.find(getDefault().getBundle(), path, null);
		
		if(url != null){
			try {
				return new File(FileLocator.toFileURL(url).toURI()).getAbsolutePath();
			} catch (URISyntaxException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return relativePath;
	}
	
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	/**
	 * Returns the shared instance
	 *
	 * @return the shared instance
	 */
	public static GapidtActivator getDefault() {
		return plugin;
	}
	
	/** 
	 * Initializes a preference store with default preference values 
	 * for this plug-in.
	 */
	protected void initializeDefaultPreferences(IPreferenceStore store) {
		logger.debug("Initializing default preferences for GAPIDT plugin");
		
		store.setDefault(MIN_SIMILARITY_DEGREE_PREFERENCE, InappropriateOrLackingCommentsDetector.getMinSimilarityDegree());
		
		store.setDefault(WHATEVER_TYPES_PREFERENCE, StringUtils.join(WhateverTypesDetector.getWhateverTypes()));
		
		store.setDefault(UNDERCOVER_FAULT_NAMES_PREFERENCE, StringUtils.join(UndercoverFaultInformationDetector.getUndercoverFaultNames()));
		
		store.setDefault(AMBIGUOUS_NAMES_PREFERENCE, StringUtils.join(SemanticAnalyzer.getAmbiguousNames()));
		
		store.addPropertyChangeListener(new IPropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent event) {
				logger.debug("Property "+event.getProperty()+" changed to '"+event.getNewValue().toString()+"'");
				
				if(event.getProperty() == MIN_SIMILARITY_DEGREE_PREFERENCE){
					InappropriateOrLackingCommentsDetector.setMinSimilarityDegree(Integer.parseInt(event.getNewValue().toString()));
				}else if(event.getProperty() == WHATEVER_TYPES_PREFERENCE){
					WhateverTypesDetector.setWhateverTypes(StringUtils.splitAndTrim(event.getNewValue().toString()));
				}else if(event.getProperty() == UNDERCOVER_FAULT_NAMES_PREFERENCE){
					UndercoverFaultInformationDetector.setUndercoverFaultNames(StringUtils.splitAndTrim(event.getNewValue().toString()));
				}else if(event.getProperty() == AMBIGUOUS_NAMES_PREFERENCE){
					SemanticAnalyzer.setAmbiguousNames(StringUtils.splitAndTrim(event.getNewValue().toString()));
				}
			}
		});
	}
	
	public static String getPreferenceLabel(String preferenceKey){
		return Locale.getMessage("preferences."+preferenceKey+".label");
	}
	
	/**
	 * Returns an image descriptor for the image file at the given
	 * plug-in relative path
	 *
	 * @param path the path
	 * @return the image descriptor
	 */
	public static ImageDescriptor getImageDescriptor(String path) {
		return imageDescriptorFromPlugin(PLUGIN_ID, path);
	}
}
